//copy from "github.com/ethereum/go-ethereum/core/vm/stack.go" with little modification
package core

import (
	"github.com/holiman/uint256"
)

const (
	StackLimit = 1024
)

type Stack struct {
	data []uint256.Int
	max  int
}

func NewStack() *Stack {
	return &Stack{
		max: StackLimit,
	}
}

func (s *Stack) GetData() []uint256.Int {
	return s.data
}

func (s *Stack) Push(num *uint256.Int) {
	s.data = append(s.data, *num)
}

func (s *Stack) Pop() (res uint256.Int) {
	res = s.data[len(s.data)-1]
	s.data = s.data[:(len(s.data) - 1)]
	return
}

func (s *Stack) Peek() *uint256.Int {
	res := &s.data[len(s.data)-1]
	return res
}

func (s *Stack) Len() int {
	return len(s.data)
}

// Back returns the n'th item in stack
func (s *Stack) Back(n int) *uint256.Int {
	return &s.data[s.Len()-n-1]
}

func (s *Stack) Dup(n int) {
	s.Push(&s.data[s.Len()-n])
}

func (s *Stack) Swap(n int) {
	s.data[s.Len()-n], s.data[s.Len()-1] = s.data[s.Len()-1], s.data[s.Len()-n]
}

func MinSwapStack(n int) int {
	return MinStack(n, n)
}
func MaxSwapStack(n int) int {
	return MaxStack(n, n)
}

func MinDupStack(n int) int {
	return MinStack(n, n+1)
}
func MaxDupStack(n int) int {
	return MaxStack(n, n+1)
}

func MaxStack(pop, push int) int {
	return int(StackLimit) + pop - push
}
func MinStack(pops, push int) int {
	return pops
}
